package chen.huai.jie.spring.xmlconfig.component.interceptor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.NamedThreadLocal;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Map;

/**
 * Created by huaijie.chen on 2016/9/26.
 */
public class RequestTimingInterceptor implements HandlerInterceptor {
    private Logger logger = LoggerFactory.getLogger(RequestTimingInterceptor.class.getSimpleName());
    private NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("Process-StartTime");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        long beginTime = System.currentTimeMillis();
        startTimeThreadLocal.set(beginTime);//线程绑定变量（该数据只有当前请求的线程可见）
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception {
        long endTime = System.currentTimeMillis();
        long beginTime = startTimeThreadLocal.get();
        long consumedTime = endTime - beginTime;

        String paramsString = "";
        if (logger.isDebugEnabled()) {
            StringBuilder buffer = new StringBuilder();
            Map<String, String[]> params = request.getParameterMap();
            buffer.append(" | Parameters:{");
            String[] keys = new String[params.size()];
            params.keySet().toArray(keys);
            for (int ii = 0; ii < keys.length; ii++) {
                if (ii > 0) {
                    buffer.append(",");
                }
                String key = keys[ii];
                buffer.append(key + ": " + Arrays.toString(params.get(key)));
            }
            buffer.append("}");

            paramsString = buffer.toString();
        }

        String timingMsg = String.format("[%d ms] [%d] [%s] %s %s%s", consumedTime, response.getStatus(), getRemortIP(request), request.getMethod(), request.getRequestURI(), paramsString);
        logger.info(timingMsg);
    }

    /**
     * 获取远程客户端的IP地址
     *
     * @param request
     * @return
     */
    private String getRemortIP(HttpServletRequest request) {
        String remoteIP = request.getHeader("x-forwarded-for");
        if (remoteIP != null) {
            return remoteIP;
        }
        return request.getRemoteAddr();
    }
}
